package com.github.aloxc.plugin.restplus.method.action;

import com.github.aloxc.plugin.restplus.action.PushYapiAction;
import com.github.aloxc.plugin.restplus.common.Consts;
import com.github.aloxc.plugin.restplus.common.PsiAnnotationHelper;
import com.github.aloxc.plugin.restplus.common.PsiMethodHelper;
import com.github.aloxc.plugin.restplus.component.ServiceNode;
import com.github.aloxc.plugin.restplus.navigation.action.RestServiceItem;
import com.github.aloxc.plugin.restplus.navigator.RestServiceDetail;
import com.github.aloxc.plugin.restplus.navigator.RestServicesNavigator;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.util.OpenSourceUtil;
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtNamedFunction;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 在文件内容左边的竖栏上显示运行按钮的处理方法
 */
public class FeignLineMarkerHandler implements GutterIconNavigationHandler {
    @Override
    public void navigate(MouseEvent mouseEvent, PsiElement psiElement) {
        try {
//            PopupBalloon.showPopupBalloon(new RelativePoint(mouseEvent), I18Bundle.getMessage("com.github.aloxc.plugin.restplus.EditorPopupMenu.run.usercase.noinit.text"), false);
            PsiMethod psiMethod = null;
            PsiClass psiClass = null;
            String path = null;
            if (psiElement instanceof PsiMethod) {
                psiMethod = (PsiMethod) psiElement;
            }
            if(psiMethod == null){
                return;
            }
            Project project = psiMethod.getProject();
            for (PsiAnnotation annotation : psiMethod.getContainingClass().getAnnotations()) {
                String qualifiedName = annotation.getQualifiedName();
                if (Consts.SpringCloud.FEIGN_ANNOTATION.equals(qualifiedName)) {
                    path = PsiAnnotationHelper.getAnnotationAttributeValue(annotation,"path");
                    break;
                }
            }

            PsiAnnotation psiAnnotation = null;

            for (PsiAnnotation annotation : psiMethod.getAnnotations()) {
                if (PsiMethodHelper.isRestfulMethodAnnotation(psiMethod,annotation)) {
                    path += PsiAnnotationHelper.getAnnotationAttributeValue(annotation,"value");
                    psiAnnotation = annotation;
                    break;
                }
            }
            String qualifiedName = psiAnnotation.getQualifiedName();
            path = path.replaceAll("//","/");
            RestServicesNavigator servicesNavigator = project.getComponent(RestServicesNavigator.class);
            TreeModel treeModel = servicesNavigator.getUrlTree().getModel();
            TreePath treePath = find((DefaultMutableTreeNode) treeModel.getRoot(), path,qualifiedName);
            if (treePath != null) {
                expandAll(servicesNavigator.getUrlTree(), new TreePath(treeModel.getRoot()), true);
                servicesNavigator.getUrlTree().setSelectionPath(treePath);
                servicesNavigator.getUrlTree().scrollPathToVisible(treePath);
                ServiceNode node = (ServiceNode) treePath.getLastPathComponent();
                if(!node.getRestServiceItem().isSwagger()) {
                    OpenSourceUtil.navigate(node.getRestServiceItem().getPsiMethod());
                }
            }
        } catch (Exception ex) {

        }
    }


    private void expandAll(JTree tree, TreePath parent, boolean expand) {
        TreeNode node = (TreeNode) parent.getLastPathComponent();
        if (node.getChildCount() > 0) {
            for (Enumeration e = node.children(); e.hasMoreElements(); ) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                expandAll(tree, path, expand);

            }
        }
        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }
    }
    private TreePath find(DefaultMutableTreeNode root, String path,String qualifiedName) {
        @SuppressWarnings("unchecked")
        Enumeration<TreeNode> e = root.depthFirstEnumeration();
        while (e.hasMoreElements()) {
            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) e.nextElement();
            if (treeNode instanceof ServiceNode) {
                ServiceNode node = (ServiceNode) treeNode;

                if(!node.isSwagger()) {

                    if (node.getRestServiceItem().getUrl().equalsIgnoreCase(path) && node.getRestServiceItem().getPsiMethod().getAnnotation(qualifiedName) != null) {
                        return new TreePath(node.getPath());
                    }
                }
            }
        }
        return null;
    }
}
